import * as signalR from '@microsoft/signalr';
import { defineStore } from 'pinia';
import { computed, ref, unref } from 'vue';

import {
  authorizationToken as authorizationTokenApi,
  changePassword as changePasswordApi,
  changeUserEmail as changeUserEmailApi,
  changeUserPhone as changeUserPhoneApi,
  checkLogin as checkLoginApi,
  logout as logoutApi,
  phoneToken as phoneTokenApi,
  profile as profileApi,
  profileEdit as profileEditApi,
  setOrganization as setOrganizationApi,
  token as tokenApi,
} from '@/api/identity';
import {
  AuthorizationTokenDto,
  ChangePasswordDto,
  EmailEditDto,
  LoginDto,
  PhoneEditDto,
  PhoneTokenDto,
  ProfileEditDto,
  TokenDto,
} from '@/api/identity/model';
import { ExchangeQuotationEnum } from '@/enums/exchangeQuotationEnum';
import { isBase64 } from '@/enums/regexEnum';
import headerImg from '@/static/images/avatars/totoro.png';
import anonymImg from '@/static/images/icons/avatar_bird_blue@128x.png';
import { useAuthStore } from '@/store/modules/auth';
import type { JsonWebToken, UserInfo } from '#/identity';
import type { ErrorMessageMode } from '#/request';
import { NavigateToUrlType } from '#/go';

import { usePreferenceStore } from './preference';
import { useProxyStore } from './proxy';

/** 首页路径 */
const HOME_PATH: NavigateToUrlType = import.meta.env.VITE_HOME_PATH;
/** 登录页路径 */
const LOGIN_PATH: NavigateToUrlType = import.meta.env.VITE_LOGIN_PATH;
/** 登录后跳转页路径 */
const LOGIN_GO_PATH: 'back' | 'home' | NavigateToUrlType = import.meta.env.VITE_LOGIN_GO_PATH;
/** 登出后跳转页路径 */
const LOGOUT_GO_PATH: 'login' | 'home' | NavigateToUrlType = import.meta.env.VITE_LOGOUT_GO_PATH;
/** SignalR接口地址 */
const SIGNALR_BASEURL: string = import.meta.env.VITE_SIGNALR_BASEURL;

/** 身份状态 */
interface IdentityState {
  /** 用户信息 */
  userInfo: Nullable<UserInfo>;
  /** JwtToken对象 */
  token: Nullable<JsonWebToken>;
  /** 最后刷新时间 */
  lastUpdateTime: number;
  /** SignalR集线器的连接 */
  signalrHub: Nullable<signalR.HubConnection>;
}

/** 初始状态 */
const initState: IdentityState = {
  /** 用户信息 */
  userInfo: null,
  /** JwtToken对象 */
  token: null,
  /** 最后刷新时间 */
  lastUpdateTime: 0,
  /** SignalR集线器的连接 */
  signalrHub: null,
};

/** 身份认证存储 */
export const useIdentityStore = defineStore(
  'app-identity',
  () => {
    /** 身份认证信息 */
    const state = ref<IdentityState>({ ...initState });

    /** 获取用户信息 */
    const getUserInfo = computed(() => unref(state).userInfo);
    /** 获取AccessToken */
    const getAccessToken = computed(() => unref(state).token?.AccessToken);
    /** 获取JwtToken对象 */
    const getToken = computed(() => unref(state).token);
    /** 获取最后刷新时间 */
    const getLastUpdateTime = computed(() => unref(state).lastUpdateTime);
    /** 获取SignalR集线器的连接 */
    const getSignalRHub = computed(() => unref(state).signalrHub);

    /** 获取头像 */
    const getAvatar = computed(() => getUserInfo.value?.Avatar || anonymImg);
    /** 是否已登录 */
    const isLogined = computed(() => !!getAccessToken.value);

    const { set: setPreference, reset: resetPreference } = usePreferenceStore();
    const { join: joinProxy } = useProxyStore();

    /** 设置用户信息 */
    const setUserInfo = (userInfo: UserInfo | null) => {
      state.value = { ...unref(state), userInfo, lastUpdateTime: new Date().getTime() };
    };

    /**
     * 设置JwtToken
     * @param token JwtToken模型
     */
    const setToken = async (token?: JsonWebToken | null) => {
      if (token) {
        state.value = { ...unref(state), token };
        await refreshUser();
      } else {
        await reset();
      }
    };

    /** 重置 */
    const reset = async () => {
      state.value = {
        ...unref(state),
        token: null,
        userInfo: null,
      };

      resetPreference();
      await refreshUser();
      await disconnectSignalRHub();
    };

    /** 登录（login） */
    const login = async (
      params: TokenDto & {
        go?: 'back' | 'home' | NavigateToUrlType;
        mode?: ErrorMessageMode;
      },
    ): Promise<UserInfo | null> => {
      try {
        const { go = LOGIN_GO_PATH, mode, ...loginParams } = params;
        const result = await tokenApi(loginParams, mode);
        if (result.Data) {
          const token = result.Data as JsonWebToken;
          await loginEnd(token);

          return await afterLoginAction(go);
        }
        return null;
      } catch (error) {
        return Promise.reject(error);
      }
    };
    /** 使用手机号码登录 */
    const phoneLogin = async (
      params: PhoneTokenDto & {
        go?: 'back' | 'home' | NavigateToUrlType;
        mode?: ErrorMessageMode;
      },
    ): Promise<UserInfo | null> => {
      try {
        const { go = LOGIN_GO_PATH, mode, ...loginParams } = params;
        const result = await phoneTokenApi(loginParams, mode);
        if (result.Data) {
          const token = result.Data as JsonWebToken;
          await loginEnd(token);

          return await afterLoginAction(go);
        }
        return null;
      } catch (error) {
        return Promise.reject(error);
      }
    };
    /** 使用授权码登录 */
    const authorizationLogin = async (
      params: AuthorizationTokenDto & {
        go?: 'back' | 'home' | NavigateToUrlType;
        mode?: ErrorMessageMode;
      },
    ): Promise<UserInfo | null> => {
      try {
        const { go = LOGIN_GO_PATH, mode, ...loginParams } = params;
        const result = await authorizationTokenApi(loginParams, mode);
        if (result.Data) {
          const token = result.Data as JsonWebToken;
          await loginEnd(token);

          return await afterLoginAction(go);
        }
        return null;
      } catch (error) {
        return Promise.reject(error);
      }
    };
    /** 设置当前组织机构 */
    const setOrganization = async (
      params: { organizationId: string } & {
        mode?: ErrorMessageMode;
      },
    ): Promise<UserInfo | null> => {
      const { mode, ...setOrganizationParams } = params;
      const result = await setOrganizationApi(setOrganizationParams.organizationId, mode);
      if (result.Data) {
        const token = result.Data as JsonWebToken;
        await loginEnd(token);

        return await afterLoginAction(undefined);
      }
      return null;
    };
    /**
     * 登录完成后程序处理
     * @param token JwtToken模型
     */
    const loginEnd = async (token: JsonWebToken) => {
      // 设置Token
      await setToken(token);
      // 初始化SignalR连接
      await connectSignalRHub();
    };

    /** 验证登录（Check Login） */
    const checkLogin = async (
      params: LoginDto & {
        mode?: ErrorMessageMode;
      },
    ) => {
      const { mode = 'none', ...loginParams } = params;
      const result = await checkLoginApi(loginParams, mode);
      return result;
    };
    /**
     * 登录后操作
     * @param go 跳转路径
     * @returns 用户信息
     */
    const afterLoginAction = async (
      go?: 'back' | 'home' | NavigateToUrlType,
    ): Promise<UserInfo | null> => {
      const accessToken = unref(getAccessToken);
      if (!accessToken) {
        return null;
      }
      // get user info
      const userInfo = await getUserInfoAction();

      if (go) {
        const pages = getCurrentPages();
        let currentRoute = '';
        if (pages && pages.length > 0) {
          const currentPage = pages[pages.length - 1];
          if (currentPage.route) {
            currentRoute = currentPage.route;
          }
        }
        const route = go?.toLowerCase();
        const path = route === 'back' ? '' : route === 'home' ? HOME_PATH : go;
        if (
          currentRoute?.replace(/^\/+/, '')?.replace(/\/+$/, '')?.split('?')[0]?.toLowerCase() !==
          path?.replace(/^\/+/, '')?.replace(/\/+$/, '')?.split('?')[0]?.toLowerCase()
        ) {
          switch (route) {
            case 'back':
              if (pages && pages.length > 1) {
                // 存在上级页面，直接返回
                uni.navigateBack();
              } else {
                // 不存在上级页面，跳转到主页
                // uni.switchTab({
                //   url: HOME_PATH,
                // });
                uni.reLaunch({
                  url: HOME_PATH?.startsWith('/') ? HOME_PATH : `/${HOME_PATH}`,
                  passedParams: {
                    info: 'Logged-in',
                  },
                });
              }
              break;
            case 'home':
              uni.reLaunch({
                url: path?.startsWith('/') ? path : `/${path}`,
                passedParams: {
                  info: 'Logged-in',
                },
              });
              break;
            default:
              // const allPages = getAllPages(null).map((page) => page.path);
              // if (allPages.includes(path)) {
              //   uni.reLaunch({
              //     url: path?.startsWith('/') ? path : `/${path}`,
              //     passedParams: {
              //       info: 'Logged-in',
              //     },
              //   });
              // }
              uni.reLaunch({
                url: path?.startsWith('/') ? path : `/${path}`,
                passedParams: {
                  info: 'Logged-in',
                },
              });
              break;
          }
        }
      }

      return userInfo;
    };
    /**
     * 获取用户信息操作
     * @returns 用户信息
     */
    const getUserInfoAction = async (): Promise<UserInfo | null> => {
      const userInfo = await refreshUser();
      return userInfo;
    };
    /** 注销（logout） */
    const logout = async (
      go: 'login' | 'home' | NavigateToUrlType = LOGOUT_GO_PATH,
      mode: ErrorMessageMode = 'none',
    ) => {
      const accessToken = unref(getAccessToken);
      if (accessToken) {
        try {
          await logoutApi(mode);
        } catch (ex) {
          console.error('注销错误', ex);
        }
      }
      await setToken(undefined);
      setUserInfo(null);
      if (go) {
        // 页面跳转
        const pages = getCurrentPages();
        let currentRoute = '';
        if (pages && pages.length > 0) {
          const currentPage = pages[pages.length - 1];
          if (currentPage.route) {
            currentRoute = currentPage.route;
          }
        }
        const route = go?.toLowerCase();
        const path = route === 'login' ? LOGIN_PATH : route === 'home' ? HOME_PATH : go;
        if (
          currentRoute?.replace(/^\/+/, '')?.replace(/\/+$/, '')?.split('?')[0]?.toLowerCase() !==
          path?.replace(/^\/+/, '')?.replace(/\/+$/, '')?.split('?')[0]?.toLowerCase()
        ) {
          switch (route) {
            case 'login':
              uni.navigateTo({
                url: path?.startsWith('/') ? path : `/${path}`,
                passedParams: {
                  info: 'Logged-out',
                },
              });
              break;
            case 'home':
              uni.reLaunch({
                url: path?.startsWith('/') ? path : `/${path}`,
                passedParams: {
                  info: 'Logged-out',
                },
              });
              break;
            default:
              // const allPages = getAllPages(null).map((page) => page.path);
              // if (allPages.includes(path)) {
              //   uni.reLaunch({
              //     url: path?.startsWith('/') ? path : `/${path}`,
              //     passedParams: {
              //       info: 'Logged-out',
              //     },
              //   });
              // }
              uni.reLaunch({
                url: path?.startsWith('/') ? path : `/${path}`,
                passedParams: {
                  info: 'Logged-out',
                },
              });
              break;
          }
        }
      }
      await refreshAuthInfo();
    };

    /** 编辑用户信息 */
    const profileEdit = async (
      params: ProfileEditDto & { mode?: ErrorMessageMode },
    ): Promise<UserInfo | null> => {
      const { mode, ...profileEditParams } = params;
      const result = await profileEditApi(profileEditParams, mode);
      if (result.Succeeded) {
        const userInfo = await refreshUser();
        return userInfo;
      }
      return null;
    };
    /** 修改密码 */
    const changePassword = async (
      params: ChangePasswordDto & { mode?: ErrorMessageMode },
    ): Promise<UserInfo | null> => {
      const { mode, ...changePasswordParams } = params;
      const result = await changePasswordApi(changePasswordParams, mode);
      if (result.Succeeded) {
        const userInfo = await refreshUser();
        return userInfo;
      }
      return null;
    };
    /** 邮箱变更 */
    const changeEmail = async (
      params: EmailEditDto & { mode?: ErrorMessageMode },
    ): Promise<UserInfo | null> => {
      const { mode, ...emailEditParams } = params;
      const result = await changeUserEmailApi(emailEditParams, mode);
      if (result.Succeeded) {
        const userInfo = await refreshUser();
        return userInfo;
      }
      return null;
    };
    /** 手机变更 */
    const changePhone = async (
      params: PhoneEditDto & { mode?: ErrorMessageMode },
    ): Promise<UserInfo | null> => {
      const { mode, ...phoneEditParams } = params;
      const result = await changeUserPhoneApi(phoneEditParams, mode);
      if (result.Succeeded) {
        const userInfo = await refreshUser();
        return userInfo;
      }
      return null;
    };
    /** 刷新用户信息 */
    const refreshUser = async (): Promise<UserInfo | null> => {
      const profileDto = await profileApi();
      if (profileDto === undefined || profileDto === null) {
        state.value = { ...unref(state), userInfo: null };
        return null;
      }
      const userInfo: UserInfo = {
        UserId: profileDto.UserId,
        UserName: profileDto.UserName,
        NickName: profileDto.NickName,
        Email: profileDto.Email,
        PhoneNumber: profileDto.PhoneNumber,

        Avatar: profileDto.Avatar,
        Signature: profileDto.Signature,

        Gender: profileDto.Gender,
        Birthday: profileDto.Birthday,
        BloodType: profileDto.BloodType,
        Tag: profileDto.Tag,
        Title: profileDto.Title,
        Address: profileDto.Address,
        Profile: profileDto.Profile,
        Sign: profileDto.Sign,
        Remark: profileDto.Remark,

        HomePath: profileDto.HomePath,

        ChineseBirthday: profileDto.ChineseBirthday,
        Age: profileDto.Age,
        ZodiacSign: profileDto.ZodiacSign,
        StarSign: profileDto.StarSign,

        IsAdmin: profileDto.IsAdmin,

        IsRefreshNext: profileDto.IsRefreshNext,

        Roles: profileDto.Roles,

        CurrentOrganization: profileDto.CurrentOrganization,
        CurrentDepartment: profileDto.CurrentDepartment,

        ExtendData: profileDto.ExtendData,
      };
      // 处理用户头像
      if (userInfo.Avatar === undefined || userInfo.Avatar === null || userInfo.Avatar === '') {
        userInfo.Avatar = headerImg;
      }
      if (!isBase64(userInfo.Avatar)) {
        // #ifdef H5
        if (JSON.parse(__VITE_WEB_PROXY__)) {
          // 啥都不需要做
        } else {
          userInfo.Avatar = joinProxy(profileDto.Avatar);
        }
        // #endif
        // 非H5正常拼接
        // #ifndef H5
        userInfo.Avatar = joinProxy(profileDto.Avatar);
        // #endif
      }
      // 设置用户
      setUserInfo(userInfo);
      // 刷新授权信息
      const roles = userInfo?.Roles?.map((m) => `${m.Id}`) || [];
      await refreshAuthInfo(roles);

      // TODO:获取及设置系统偏好设置项（可以通过远程Api的方式获取，建议封装成独立方法）
      setPreference({
        Id: '1',
        OrganizationId: userInfo?.CurrentOrganization?.Id,
        Initialized: true,
        CEO: '',
        CFO: '',
        MainCurrencyId: 'CNY',
        SysCurrencyId: 'CNY',
        ExchangeQuotation: ExchangeQuotationEnum.DirectQuotation,
        QuantityAccuracy: 4,
        PriceAccuracy: 6,
        AmountAccuracy: 2,
        RateAccuracy: 4,
        PercentageAccuracy: 4,
        MeasureAccuracy: 4,
        CompanyName: userInfo?.CurrentOrganization?.Name ? userInfo.CurrentOrganization.Name : '',
        TaxpayerNumber: '',
        CompanyAddr: '',
        CompanyTel: '',
        CompanyBank: '',
        CompBakAccount: '',
      });

      return userInfo;
    };
    /** 刷新授权信息 */
    const refreshAuthInfo = async (roles?: string[]) => {
      const authStore = useAuthStore();
      authStore.setAuthType('code');
      await authStore.refresh(roles);
    };

    /**
     * 尝试刷新AccessToken和RefreshToken，检测AccessToken有效期，如过期则使用RefreshToken来刷新
     * @param mode 错误消息模型
     */
    const tryRefreshToken = async (mode: ErrorMessageMode = 'none') => {
      const token = unref(getToken);
      if (token) {
        // const diff = Math.round((token.AccessTokenExpiresUtc - new Date().valueOf()) / 1000);
        const seconds = new Date().valueOf();
        const accessTokenExpiresUtc = token.AccessTokenExpiresUtc
          ? Number(token.AccessTokenExpiresUtc)
          : 0;
        const diff = (accessTokenExpiresUtc - seconds) / 1000;
        // console.log('tryRefreshToken', { accessTokenExpiresUtc, seconds, diff });
        // 检测Token的有效期和当前时间相差小于300秒时，执行刷新Token，否则跳过
        if (diff > 300) {
          return;
        }
        if (token.RefreshToken) {
          await refreshToken(token.RefreshToken, mode);
        }
      }
    };
    /**
     * 使用现在的RefreshToken刷新新的AccessToken与RefreshToken
     * @param refreshToken 现有的RefreshToken
     * @param mode 错误消息模型
     */
    const refreshToken = async (
      refreshToken: string,
      mode: ErrorMessageMode = 'none',
    ): Promise<UserInfo | null> => {
      // const { createMessage } = useMessage();
      try {
        // 使用RefreshToken刷新AccessToken
        const dto: TokenDto = { RefreshToken: refreshToken, GrantType: 'refresh_token' };
        const result = await tokenApi(dto, mode);
        const token = result.Data as JsonWebToken;
        await loginEnd(token);

        // get user info
        const userInfo = await getUserInfoAction();
        return userInfo;
      } catch (error) {
        console.error(error);
        return null;
      }
    };

    /** 连接SignalR集线器 */
    const connectSignalRHub = async () => {
      let { signalrHub } = state.value;
      if (signalrHub !== null) {
        // 如果已经连接，则返回
        if (
          signalrHub.state === signalR.HubConnectionState.Connected ||
          signalrHub.state === signalR.HubConnectionState.Connecting ||
          signalrHub.state === signalR.HubConnectionState.Reconnecting
        ) {
          return;
        } else {
          signalrHub = null;
        }
      }

      let signalrHubUrl = SIGNALR_BASEURL;
      // #ifdef H5
      if (JSON.parse(__VITE_WEB_PROXY__)) {
        // 啥都不需要做
      } else {
        signalrHubUrl = joinProxy(signalrHubUrl);
      }
      // #endif
      // 非H5正常拼接
      // #ifndef H5
      signalrHubUrl = joinProxy(signalrHubUrl);
      // #endif

      // SignalR
      signalrHub = new signalR.HubConnectionBuilder()
        // 服务器地址：本地站点可以直接写“/xxx”。JWT验证码：不带Bearer
        .withUrl(signalrHubUrl, { accessTokenFactory: () => unref(getAccessToken) })
        // 默认不会自动重连，需手动调用 withAutomaticReconnect
        // 如果不带任何参数，withAutomaticReconnect 会配置客户端在每一次重连尝试之前，分别等待0，2，10，30秒，如果四次重连均失败，那么连接便会停止。
        // 如果配置了自动重连，在开始每一次重连尝试之前，HubConnection 都会变为 HubConnectionState.Reconnecting 状态并触发它的onreconnecting 回调。
        // 而如果没有配置HubConnection 为自动重连，此时（连接断开时）HubConnection 的状态会变为Disconnected 并触发它的onclose 回调。
        // 这就提供了一个时机来警告用户连接已经丢失，并禁用掉相关的UI元素。
        .withAutomaticReconnect({
          nextRetryDelayInMilliseconds: (retryContext) => {
            if (retryContext.elapsedMilliseconds < 60000) {
              // 如果到目前为止我们重新连接的时间不到60秒，在下一次重新连接尝试之前的0到10秒之间。
              return Math.random() * 10000;
            } else {
              // 如果到目前为止重新连接的时间超过60秒，请停止重新连接。
              return null;
            }
          },
        })
        .build();

      // #region "客户端心跳机制在服务端发布模式下好像有问题，导致异常断开，先注释备查"
      // # SignalR服务器活动超时（毫秒）。 如果服务器未在此时间间隔内发送消息，则客户端会将服务器视为断开连接，并触发 onclose 事件。默认超时值为30000毫秒（30秒）。
      // # 此值必须足够大，以便从服务器发送 ping 消息 ，并在超时间隔内由客户端接收该消息。 建议值至少为服务器的 KeepAliveInterval 值的两倍，以允许 ping 到达的时间。
      // if (signalrServerTimeout && signalrServerTimeout > 0) {
      //   signalrHub.serverTimeoutInMilliseconds = signalrServerTimeout;
      // }

      // # SignalR确定客户端发送 ping 消息的间隔。 如果从客户端发送任何消息，则会将计时器重置为间隔的开始时间。默认值为15000毫秒（15秒）。
      // # 如果客户端未在服务器上设置的 ClientTimeoutInterval 中发送消息，则服务器会将客户端视为已断开连接。
      // # ping最多与服务器ping一样频繁。如果服务器每5秒ping一次，则低于5的值将每5秒ping一次。
      // if (signalrKeepAliveInterval && signalrKeepAliveInterval > 0) {
      //   signalrHub.keepAliveIntervalInMilliseconds = signalrKeepAliveInterval;
      // }
      // #endregion

      // signalrHub.onreconnecting(async (error) => {
      //   console.log('监听到正在连接SignalR', error);
      // });
      // signalrHub.onreconnected(async (connectionId) => {
      //   console.log('监听到连接SignalR成功', connectionId);
      // });
      signalrHub.onclose((error) => {
        console.log('监听到SignalR客户端连接关闭', error || '');
        signalrHub = null;
      });

      // signalrHub.on('AAA', (msg: string) => {
      //   const { createMessage } = useMessage();
      //   createMessage.success(msg);
      // });

      // 如果已经断开连接，则连接。
      try {
        if (
          signalrHub.state === signalR.HubConnectionState.Disconnected ||
          signalrHub.state === signalR.HubConnectionState.Disconnecting
        ) {
          await signalrHub.start();
        }
        // signalrHub.on('BBB', (msg: string) => {
        //   const { createMessage } = useMessage();
        //   createMessage.success(msg);
        // });
      } catch (error) {
        console.error('连接SignalR失败', error);
        signalrHub = null;
      }
    };

    /** 断开连接SignalR集线器 */
    const disconnectSignalRHub = async () => {
      let { signalrHub } = state.value;
      // SignalR
      if (signalrHub !== null) {
        // 如果已经连接，则断开
        if (
          signalrHub.state === signalR.HubConnectionState.Connected ||
          signalrHub.state === signalR.HubConnectionState.Connecting ||
          signalrHub.state === signalR.HubConnectionState.Reconnecting
        ) {
          await signalrHub.stop();
        }
      }
      signalrHub = null;
    };

    return {
      /** 身份认证信息 */
      state,
      /** 获取用户信息 */
      getUserInfo,
      /** 获取AccessToken */
      getAccessToken,
      /** 获取JwtToken对象 */
      getToken,
      /** 获取最后刷新时间 */
      getLastUpdateTime,
      /** 获取SignalR集线器的连接 */
      getSignalRHub,
      /** 获取头像 */
      getAvatar,
      /** 是否已登录 */
      isLogined,
      /** 登录（login） */
      login,
      /** 使用手机号码登录 */
      phoneLogin,
      /** 使用授权码登录 */
      authorizationLogin,
      /** 设置当前组织机构 */
      setOrganization,
      /** 验证登录（Check Login） */
      checkLogin,
      /** 注销（logout） */
      logout,
      /** 编辑用户信息 */
      profileEdit,
      /** 修改密码 */
      changePassword,
      /** 邮箱变更 */
      changeEmail,
      /** 手机变更 */
      changePhone,
      /** 刷新用户信息 */
      refreshUser,
      /** 刷新授权信息 */
      refreshAuthInfo,
      /**
       * 尝试刷新AccessToken和RefreshToken，检测AccessToken有效期，如过期则使用RefreshToken来刷新
       * @param mode 错误消息模型
       */
      tryRefreshToken,
      /**
       * 使用现在的RefreshToken刷新新的AccessToken与RefreshToken
       * @param refreshToken 现有的RefreshToken
       * @param mode 错误消息模型
       */
      refreshToken,
    };
  },
  {
    persist: true, // 如果需要持久化就写 true, 不需要持久化就写 false（或者去掉这个配置项）。
  },
);
